package com.mw.job.disruptor;

import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import com.lmax.disruptor.util.DaemonThreadFactory;
import com.mw.job.bean.DataBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class DisruptorMain {

	private static Logger log = LoggerFactory.getLogger(DisruptorMain.class);

	static class DataBeanFactory implements EventFactory<DataBean> {
		@Override
		public DataBean newInstance() {
			return new DataBean();
		}
	}

	private static DataBeanFactory factory = new DataBeanFactory();
	private static Disruptor<DataBean> disruptor = null;
	private static RingBuffer<DataBean> ringBuffer = null;


	public static void start(int bufferSize, int consumerThreadNum) {

		disruptor = new Disruptor(factory, bufferSize, DaemonThreadFactory.INSTANCE, ProducerType.SINGLE, new BlockingWaitStrategy());

		//添加消费者线程
		disruptor.handleEventsWithWorkerPool(consumerThread(consumerThreadNum));

		//设置异常处理器
		disruptor.setDefaultExceptionHandler(new DisruptorExceptionHandler());

		//启动 disruptor
		disruptor.start();

		ringBuffer = disruptor.getRingBuffer();// disruptor 启动后，getRingBuffer 才会有值
	}

	public static RingBuffer<DataBean> ringBuffer() {
		return ringBuffer;
	}


	private static DisruptorConsumer[] consumerThread(int num) {
		boolean flag = false;

		if (num<=0)flag = true;
		else if (!powerOf2(num))flag = true;
		if (flag) throw new RuntimeException("disruptor 消费者线程必须大于0，且是 2 的整次幂！");

		DisruptorConsumer result[] = new DisruptorConsumer[num];
		for (int i = 0; i < num; i++) {
			result[i] = new DisruptorConsumer();
		}
		return result;
	}

	//判断 num 是否为 2 的整次幂，如果是返回 true，注意：2 的 0 次幂等于 1，传入 1 也是返回 true
	private static boolean powerOf2(int num) {
		return ((num & (num - 1)) == 0);
	}

	public static void stop() {
		disruptor.shutdown();//会消费掉环形队列中的所有数据，然后再执行关闭
		log.info("终止 Disruptor 调度……");
	}

	public static void main(String[] args) {
		System.out.println("2:"+powerOf2(2));
		System.out.println("64:"+powerOf2(64));
		System.out.println("6:"+powerOf2(6));
		System.out.println("1024:"+powerOf2(1024));
		System.out.println("512:"+powerOf2(512));
		System.out.println("12:"+powerOf2(12));
		System.out.println("9:"+powerOf2(9));
	}

}












































